home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-03-22 | 34.8 KB | 1,294 lines | [TEXT/PJMM] |
- unit Camera;
-
- {Routines used by the NIH Image for supporting the Data Translation}
- {QuickCapture card, the Scion Image 1000, and the Scion LG-3.}
-
- interface
-
-
- uses
- QuickDraw, Palettes, PrintTraps, globals, Utilities, Graphics, File1, Analysis;
-
-
- procedure AverageFrames;
- procedure GetFrame;
- procedure CaptureAndDisplayFrame;
- procedure HighlightPixels;
- procedure ShowTriggerMessage;
- procedure StartDigitizing;
- procedure StopDigitizing;
- procedure SetVideoChannel;
- function GetFGPixel (h, v: integer): integer;
- procedure CopyOffscreen (src, dst: PixMapHandle; sRect, dRect: rect);
- procedure GetScionFrame (DisplayPoint: point);
- procedure WaitForTrigger;
- procedure ShowChannel;
- procedure ShowVideoControl;
- procedure UpdateVideoControl;
- procedure DoVideoControl (item: integer);
-
-
-
- implementation
-
- type
- IntPtr = ^integer;
-
- var
- SavePicBaseAddr: ptr;
- StopFlagLoc: IntPtr;
-
-
- procedure CorrectShadingOfLine (PicPtr, BFPtr: ptr; width, BFMean: integer);
- {}
- {VAR}
- { PicLine,BFLine:LinePtr;}
- { i,value:integer;}
- {BEGIN}
- { PicLine:=LinePtr(PicPtr);}
- { BFLine:=LinePtr(BFPtr);}
- { FOR i:=0 TO width-1 DO BEGIN}
- { value:=PicLine^[i];}
- { value:=255-value;}
- { value:=(LongInt(value)*BFMean+(BFLine^[i] DIV 2)) DIV BFLine^[i];}
- { IF value>254 THEN value:=254;}
- { IF value<1 THEN value:=1;}
- { PicLine^[i]:=255-value;}
- { END;}
- { }
- {a0=data pointer}
- {a1=blank field data pointer}
- {d0=count}
- {d1=pixel value}
- {d2=blank field pixel value}
- {d3=blank field mean}
- {d4=temp}
- {d5=max pixel value(245)}
- {d6=min pixel value(1)}
- inline
- $4E56, $0000, { link a6,#0}
- $48E7, $FEC0, { movem.l a0-a1/d0-d6,-(sp)}
- $206E, $000C, { move.l 12(a6),a0}
- $226E, $0008, { move.l 8(a6),a1}
- $4280, { clr.l d0}
- $302E, $0006, { move.w 6(a6),d0}
- $362E, $0004, { move.w 4(a6),d3}
- $2A3C, $0000, $00FE, { move.l #254,d5}
- $2C3C, $0000, $0001, { move.l #1,d6}
- $5380, { subq.l #1,d0}
- $4281, { clr.l d1}
- $4282, { clr.l d2}
- $1210, {L1 move.b (a0),d1}
- $1419, { move.b (a1)+,d2}
- $4601, { not.b d1}
- $C2C3, { mulu.w d3,d1}
- $2802, { move.l d2,d4}
- $E244, { asr.w #1,d4}
- $D284, { add.l d4,d1}
- $82C2, { divu.w d2,d1}
- $B245, { cmp.w d5,d1}
- $6F02, { ble.s L2}
- $3205, { move.w d5,d1}
- $B246, {L2 cmp.w d6,d1}
- $6C02, { bge.s L3}
- $3206, { move.w d6,d1}
- $4601, {L3 not.b d1}
- $10C1, { move.b d1,(a0)+}
- $51C8, $FFDE, { dbra d0,L1}
- $4CDF, $037F, { movem.l (sp)+,a0-a1/d0-d6}
- $4E5E, { unlk a6}
- $DEFC, $000C; { add.w #12,sp}
- {END;}
-
-
- procedure CorrectShading;
- var
- i: integer;
- offset: LongInt;
- p1, p2: ptr;
- str: str255;
- begin
- with info^ do begin
- if ImageSize <> BlankFieldInfo^.ImageSize then begin
- beep;
- exit(CorrectShading);
- end;
- ShowWatch;
- p1 := PicBaseAddr;
- p2 := BlankFieldInfo^.PicBaseAddr;
- for i := 1 to nLines do begin
- CorrectShadingOfLine(p1, p2, PixelsPerLine, BlankFieldMean);
- p1 := ptr(ord4(p1) + info^.BytesPerRow);
- p2 := ptr(ord4(p2) + BlankFieldInfo^.BytesPerRow);
- if i mod 96 = 0 then
- UpdatePicWindow;
- end;
- UpdatePicWindow;
- str := title;
- if SpatiallyCalibrated then
- str := concat(str, chr($13)); {Black Diamond}
- if DensityCalibrated then
- str := concat(str, '');
- if wptr <> nil then
- SetWTitle(wptr, concat(str, '(Corrected)'));
- end;
- end;
-
-
- procedure CopyOffscreen (src, dst: PixMapHandle; sRect, dRect: rect);
- var
- SaveGDevice: GDHandle;
- begin
- SaveGDevice := GetGDevice;
- SetGDevice(osGDevice);
- hlock(handle(src));
- hlock(handle(dst));
- CopyBits(BitMapHandle(src)^^, BitMapHandle(dst)^^, sRect, dRect, SrcCopy, nil);
- hunlock(handle(src));
- hunlock(handle(dst));
- SetGDevice(SaveGDevice);
- end;
-
-
- procedure StopDigitizing;
- begin
- if digitizing then
- with info^ do begin
- ShowFrameRate('', fgStartTicks, fgFrameCount);
- CopyOffscreen(fgPort^.portPixMap, osPort^.portPixMap, PicRect, PicRect);
- SetItem(SpecialMenuH, StartItem, 'Start Capturing');
- Digitizing := false;
- ContinuousHistogram := false;
- with info^ do
- if PictureType = FrameGrabberType then begin
- title := 'Camera';
- UpdateTitleBar;
- if HighlightSaturatedPixels then
- LoadLUT(ctable);
- end;
- if (BlankFieldInfo <> nil) and not OptionKeyDown then
- CorrectShading;
- end;
- end;
-
-
- procedure GetFrame;
- var
- ticks, timeout: LongInt;
- begin
- if FrameGrabber = ScionLG3 then begin
- if ExternalTrigger then begin {Wait for trigger}
- ControlReg^ := $90;
- repeat
- if button then
- ExternalTrigger := false;
- until (BitAnd(ControlReg^, $80) = $80) or not ExternalTrigger;
- ControlReg^ := 0;
- if Digitizing then
- StopDigitizing;
- UpdateVideoControl;
- end {if External Trigger}
- else begin
- TimeOut := TickCount + 30; {1/2sec. timeout}
- ControlReg^ := $80; {Start frame capture}
- while BitAnd(ControlReg^, $80) = 0 do begin {Wait for it to complete}
- if TickCount > TimeOut then begin
- ControlReg^ := 0;
- leave
- end;
- end;
- ControlReg^ := 0;
- end;
- end
- else begin {QuickCapture}
- if ExternalTrigger then begin {Wait for trigger}
- ControlReg^ := BitAnd($82, 255);
- repeat
- if button then
- ExternalTrigger := false;
- until (ControlReg^ >= 0) or not ExternalTrigger;
- if Digitizing then
- StopDigitizing;
- UpdateVideoControl;
- end {if External Trigger}
- else begin
- TimeOut := TickCount + 30; {1/2sec. timeout}
- ControlReg^ := BitAnd($80, 255); {Start frame capture}
- while ControlReg^ < 0 do begin {Wait for it to complete}
- if TickCount > TimeOut then
- leave
- end;
- end;
- end; {QuickCapture}
- fgFrameCount := fgFrameCount + 1;
- end;
-
-
- procedure CaptureAndDisplayFrame;
- var
- tPort: GrafPtr;
- begin
- with info^ do begin
- if (PictureType <> FrameGrabberType) or (PixelsPerLine <> fgWidth) or (nlines <> fgHeight) then begin
- Digitizing := false;
- exit(CaptureAndDisplayFrame);
- end;
- GetFrame;
- getPort(tPort);
- SetPort(wptr);
- hlock(handle(fgPort^.portPixMap));
- hlock(handle(CGrafPort(wptr^).PortPixMap));
- CopyBits(BitMapHandle(fgPort^.portPixMap)^^, BitMapHandle(CGrafPort(wptr^).PortPixMap)^^, SrcRect, wrect, gCopyMode, nil);
- hunlock(handle(fgPort^.portPixMap));
- hunlock(handle(CGrafPort(wptr^).PortPixMap));
- SetPort(tPort);
- end;
- end;
-
-
- procedure SetReg (index, value: integer);
- const
- RegOffset = $f5fe0;
- var
- reg: ptr;
- begin
- reg := ptr(fgSlotBase + RegOffset + index * 4);
- reg^ := value;
- end;
-
-
- procedure ResetScion (GrabRect: rect; DisplayPoint: point);
- const
- ilutOffset = $f0000;
- LineStartsRamOffset = $f4000;
- type
- LineStartsArray = packed array[0..8191] of UnsignedByte;
- LineStartsType = ^LineStartsArray;
- var
- ScreenRowBytesx2: LongInt;
- LutPtr: ptr;
- LineStarts: LineStartsType;
- EvenStart, OddStart: LongInt;
- width, height, IndexOdd, IndexEven, index, i: integer;
- hstart, vstart: integer;
- begin
- ScreenRowBytesx2 := ScreenRowBytes * 2;
- LoadInputLUT(Ptr(fgSlotBase + ilutOffset));
- with GrabRect, DisplayPoint do begin
- hstart := BitAnd(left, $fffc);
- vstart := BitAnd(top, $fffe);
- width := right - left;
- height := bottom - top;
- StopFlagLoc := IntPtr(LongInt(ScreenBase) + h + ScreenRowBytes * (v + height - 2) + 4);
- EvenStart := LongInt(ScreenBase) + h + ScreenRowBytes * v;
- OddStart := EvenStart + ScreenRowBytes;
- IndexOdd := 0;
- IndexEven := (height div 2) * 16;
- end;
- LineStarts := LineStartsType(fgSlotBase + LineStartsRamOffset);
- for i := 1 to height div 2 do begin
- LineStarts^[IndexOdd] := BSR(BitAnd(OddStart, $ff000000), 24);
- LineStarts^[IndexOdd + 4] := BSR(BitAnd(OddStart, $ff0000), 16);
- LineStarts^[IndexOdd + 8] := BSR(BitAnd(OddStart, $ff00), 8);
- LineStarts^[IndexOdd + 12] := BitAnd(OddStart, $fc);
- LineStarts^[IndexEven] := BSR(BitAnd(EvenStart, $ff000000), 24);
- LineStarts^[IndexEven + 4] := BSR(BitAnd(EvenStart, $ff0000), 16);
- LineStarts^[IndexEven + 8] := BSR(BitAnd(EvenStart, $ff00), 8);
- LineStarts^[IndexEven + 12] := BitAnd(EvenStart, $fc);
- IndexOdd := IndexOdd + 16;
- IndexEven := IndexEven + 16;
- OddStart := OddStart + ScreenRowBytesx2;
- EvenStart := EvenStart + ScreenRowBytesx2;
- end;
- Index := height * 16;
- LineStarts^[Index] := 0;
- LineStarts^[Index + 4] := 0;
- LineStarts^[Index + 8] := 0;
- LineStarts^[Index + 12] := 1;
- SetReg(1, 0);
- SetReg(2, 162 - (width div 4));
- SetReg(3, 0);
- SetReg(4, 225 - (hstart div 4));
- SetReg(5, 255 - (width div 4));
- SetReg(6, 241 - (vstart div 2));
- SetReg(7, 255 - (height div 2));
- end;
-
-
- procedure GetScionFrame (DisplayPoint: point);
- {Captures a single Scion frame to screen memory.}
- type
- IntPtr = ^integer;
- var
- FlagLoc: IntPtr;
- StartTime: LongInt;
- myMMUMode: signedbyte;
- begin
- with DisplayPoint do
- FlagLoc := IntPtr(LongInt(ScreenBase) + h + ScreenRowBytes * v + 4);
- StartTime := TickCount;
- myMMUMode := 1;
- SwapMMUMode(myMMUMode);
- FlagLoc^ := $00ff;
- SetReg(1, BitOr(128, VideoChannel * 4)); {Grab Enable}
- while FlagLoc^ = $00ff do
- if TickCount > (StartTime + 5) then begin
- SetReg(1, 0); {Stop Grabbing}
- SwapMMUMode(myMMUMode);
- exit(GetScionFrame)
- end;
- StopFlagLoc^ := $00ff;
- while StopFlagLoc^ = $00ff do begin
- end;
- SetReg(1, 0); {Stop Grabbing}
- SwapMMUMode(myMMUMode);
- end;
-
-
- function GetScreenPixel (h, v: integer): integer;
- var
- offset: LongInt;
- p: ptr;
- begin
- offset := LongInt(v) * ScreenRowBytes + h;
- p := ptr(ord4(ScreenBase) + offset);
- GetScreenPixel := BAND(p^, 255);
- end;
-
-
- procedure CopyScionFrameOffscreen (DisplayPoint: point; wwidth, wheight: integer);
- var
- src, dst: ptr;
- line: integer;
- begin
- with Info^ do begin
- with DisplayPoint do
- src := ptr(LongInt(ScreenBase) + h + ScreenRowBytes * v);
- dst := ptr(LongInt(PicBaseAddr));
- for line := 1 to wheight do begin
- BlockMove(src, dst, wwidth);
- src := ptr(ord4(src) + ScreenRowBytes);
- dst := ptr(ord4(dst) + BytesPerRow);
- end;
- end;
- end;
-
-
- procedure DoMiniEventLoop (FullScreenMode: boolean);
- var
- loc: point;
- event: EventRecord;
- begin
- FlushEvents(EveryEvent, 0);
- if not FullScreenMode then
- DrawLabels('X:', 'Y:', 'Value:');
- repeat
- GetMouse(loc);
- LocalToGlobal(loc);
- if not FullScreenMode then
- with loc do
- Show3Values(h, v, GetScreenPixel(h, v));
- until WaitNextEvent(mDownMask + KeyDownMask, Event, 0, nil);
- end;
-
-
- procedure SelectCameraWindow (grabber: PicType);
- {If there is a Camera window, activate it, otherwise, do nothing.}
- var
- i: integer;
- TempInfo: InfoPtr;
- begin
- for i := 1 to nPics do begin
- TempInfo := pointer(WindowPeek(PicWindow[i])^.RefCon);
- if grabber = TempInfo^.PictureType then begin
- if PicWindow[i] <> nil then begin
- if OpPending then
- KillRoi;
- SelectWindow(PicWindow[i]);
- Info := TempInfo;
- ActivateWindow;
- end; {if}
- leave;
- end; {if}
- end; {for}
- end;
-
-
- procedure CaptureUsingScion;
- var
- GrabRect, ScreenSrcRect: rect;
- DisplayPoint: point;
- FullScreenMode: boolean;
- wwidth, wheight: integer;
- tPort: GrafPtr;
- SaveBackgroundColor, hstart, vstart: integer;
- ignore: integer;
- mloc: point;
- MainDevice: GDHandle;
- SrcPixMap: PixMapHandle;
- myMMUMode: signedbyte;
- FlagLoc: IntPtr;
- StartTime: LongInt;
- grabbing: boolean;
- begin
- FullScreenMode := OptionKeyDown and (ScreenWidth = 640);
- if FullScreenMode or (ScreenWidth > 640) then begin
- wwidth := MaxScionWidth;
- wheight := 480
- end
- else begin
- wwidth := 552;
- if wwidth > MaxScionWidth then
- wwidth := MaxScionWidth;
- wheight := 436;
- end;
- SelectCameraWindow(ScionType);
- with Info^ do
- if PictureType = ScionType then
- with wrect do
- if (wwidth <> right) or (wheight <> bottom) then begin
- changes := false;
- ignore := CloseAWindow(wptr);
- end;
- with info^ do
- if PictureType <> ScionType then begin
- if not NewPicWindow('Camera(Scion)', wwidth, wheight) then begin
- beep;
- exit(CaptureUsingScion)
- end;
- end;
- KillRoi;
- with info^ do begin
- PictureType := ScionType;
- changes := true;
- UpdateTitleBar;
- end;
- hstart := (640 - wwidth) div 2;
- vstart := (480 - wheight) div 2;
- SetRect(GrabRect, hstart, vstart, hstart + wwidth, vstart + wheight);
- if FullScreenMode then
- with DisplayPoint do begin
- h := BitAnd((640 - wwidth) div 2, $fffc);
- v := 0;
- end
- else
- with DisplayPoint do begin
- h := PicLeftBase;
- v := PicTopBase;
- end;
- ResetScion(GrabRect, DisplayPoint);
- if FullScreenMode then begin
- GetPort(tPort);
- SaveBackgroundColor := BackgroundIndex;
- SetBackgroundColor(BlackIndex);
- EraseScreen;
- end;
- if info^.magnification <> 1.0 then
- Unzoom;
- with DisplayPoint do
- FlagLoc := IntPtr(LongInt(ScreenBase) + h + ScreenRowBytes * v + 4);
- StartTime := TickCount;
- grabbing := true;
- myMMUMode := 1;
- SwapMMUMode(myMMUMode);
- FlagLoc^ := $00ff;
- SetReg(1, BitOr(128, VideoChannel * 4)); {Grab Enable}
- while FlagLoc^ = $00ff do
- if TickCount > (StartTime + 5) then begin
- SetReg(1, 0); {Stop Grabbing}
- FlagLoc^ := $0000;
- SwapMMUMode(myMMUMode);
- grabbing := false;
- end;
- if grabbing then begin
- SwapMMUMode(myMMUMode);
- DoMiniEventLoop(FullScreenMode);
- myMMUMode := 1;
- SwapMMUMode(myMMUMode);
- StopFlagLoc^ := $00ff;
- while StopFlagLoc^ = $00ff do begin
- end;
- SetReg(1, 0); {Stop Grabbing}
- SwapMMUMode(myMMUMode);
- HideCursor;
- GetScionFrame(DisplayPoint);
- end;
- MainDevice := GetMainDevice;
- SrcPixMap := MainDevice^^.gdPMap;
- with DisplayPoint, ScreenSrcRect do begin
- left := h;
- top := v;
- right := left + wwidth;
- bottom := top + wheight;
- end;
- with info^ do begin
- CopyOffscreen(SrcPixMap, osPort^.portPixMap, ScreenSrcRect, PicRect);
- ShowCursor;
- if FullScreenMode then begin
- RestoreScreen;
- SetBackgroundColor(SaveBackgroundColor);
- SetPort(tPort);
- end;
- title := 'Camera';
- UpdateTitleBar;
- end; {with}
- if (BlankFieldInfo <> nil) and not OptionKeyDown then
- CorrectShading;
- FlushEvents(EveryEvent, 0);
- end;
-
-
- procedure HighlightPixels;
- var
- lut: MyCSpecArray;
- begin
- with info^ do begin
- lut := ctable;
- lut[1].rgb := Highlight1;
- lut[254].rgb := Highlight254;
- LoadLUT(lut);
- end;
- end;
-
-
- procedure ShowTriggerMessage;
- begin
- if ExternalTrigger and ((FrameGrabber = QuickCapture) or (FrameGrabber = ScionLG3)) then
- ShowMessage(concat('EXTERNAL TRIGGER MODE', cr, '(Press mouse button to exit)'));
- end;
-
-
- procedure StartDigitizing;
- var
- i, width, height: integer;
- trect: rect;
- NewWindow: boolean;
- begin
- if FrameGrabber = Scion then begin
- if HighlightSaturatedPixels then
- HighlightPixels;
- CaptureUsingScion;
- if HighlightSaturatedPixels then
- LoadLUT(info^.ctable);
- exit(StartDigitizing)
- end;
- if Digitizing then begin
- StopDigitizing;
- if BlankFieldInfo <> nil then
- wait(15);
- FlushEvents(EveryEvent, 0); {In case user holds key down too long}
- exit(StartDigitizing)
- end;
- if FrameGrabber = NoFrameGrabber then begin
- PutMessage('Capturing requires a Data Translation or SCION frame grabber card.');
- exit(StartDigitizing)
- end;
- if info^.PictureType <> FrameGrabberType then
- SelectCameraWindow(FrameGrabberType);
- NewWindow := false;
- with info^ do
- if (PictureType <> FrameGrabberType) or (PixelsPerLine <> fgWidth) or (nlines <> fgHeight) then begin
- if not NewPicWindow('Camera', fgWidth, fgHeight) then
- exit(StartDigitizing);
- NewWindow := true;
- end;
- with info^ do begin
- PictureType := FrameGrabberType;
- if NewWindow and (not EqualRect(SrcRect, PicRect)) then {Center Frame}
- with SrcRect do begin
- width := right - left;
- height := bottom - top;
- left := (PicRect.right - width) div 2;
- right := left + width;
- top := (PicRect.bottom - height) div 2;
- bottom := top + height;
- end;
- KillRoi;
- if ScaleToFitWindow then
- ScaleToFit;
- with SrcRect do begin
- width := right - left;
- left := band(left, $fffc);
- right := left + width;
- end;
- GetWindowRect(wptr, trect);
- with trect do
- if band(left, 3) <> 0 then
- MoveWindow(wptr, band(left, $fffc), top, true); {Forces window to be word aligned}
- with SrcRect do {Prevents bus errors when Camera window moved.}
- if (top = 0) and (bottom < PicRect.bottom) then begin
- top := top + 1;
- bottom := bottom + 1;
- end;
- ResetFrameGrabber;
- Digitizing := true;
- SetItem(SpecialMenuH, StartItem, 'Stop Capturing');
- changes := true;
- BinaryPic := false;
- UpdateTitleBar;
- if HighlightSaturatedPixels then
- HighlightPixels;
- end; {with info}
- fgFrameCount := 0;
- fgStartTicks := TickCount;
- ContinuousHistogram := false;
- ShowTriggerMessage;
- end;
-
-
- procedure AddLineToSum (src, dst: ptr; width: LongInt);
- {$IFC false}
- type
- SumLineType = array[0..2047] of integer;
- fptr = ^SumLineType;
- var
- FrameLine: LinePtr;
- SumLine: fptr;
- i: integer;
- begin
- FrameLine := LinePtr(src);
- SumLine := fptr(dst);
- for i := 0 to width - 1 do
- SumLine^[i] := SumLine^[i] + FrameLine^[i];
- end;
- {$ENDC}
- inline
- {a0=data pointer}
- {a1=sum buffer pointer}
- {d0=count}
- {d1=pixel value}
- {d2=temp}
- $4E56, $0000, {link a6,#0}
- $48E7, $E0C0, {movem.l a0-a1/d0-d2,-(sp)}
- $206E, $000C, {move.l 12(a6),a0}
- $226E, $0008, {move.l 8(a6),a1}
- $202E, $0004, {move.l 4(a6),d0}
- $5380, {subq.l #1,d0}
- $4281, {clr.l d1}
- $4282, {clr.l d2}
- $1218, {L1 move.b (a0)+,d1}
- $3411, {move.w (a1),d2}
- $D441, {add.w d1,d2}
- $32C2, {move.w d2,(a1)+}
- $51C8, $FFF6, {dbra d0,L1}
- $4CDF, $0307, {movem.l (sp)+,a0-a1/d0-d2}
- $4E5E, {unlk a6}
- $DEFC, $000C; {add.w #12,sp}
-
-
-
- function DoAveragingOptions: boolean;
- const
- FramesID = 8;
- VideoRateID = 9;
- SumID = 10;
- ShowID = 11;
- FixID = 12;
- MinID = 13;
- MaxID = 14;
- var
- mylog: DialogPtr;
- item, i: integer;
- begin
- InitCursor;
- mylog := GetNewDialog(140, nil, pointer(-1));
- if not SumFrames then begin
- ShowIntegratedValues := false;
- FixIntegrationScale := false;
- end;
- SetDNum(MyLog, FramesID, FramesToAverage);
- SetDialogItem(mylog, SumID, ord(SumFrames));
- SetDialogItem(mylog, VideoRateID, ord(VideoRateAveraging));
- SetDialogItem(mylog, ShowID, ord(ShowIntegratedValues));
- SetDialogItem(mylog, FixID, ord(FixIntegrationScale));
- SetDNum(MyLog, MinID, IntegrationMin);
- SetDNum(MyLog, MaxID, IntegrationMax);
- SelIText(MyLog, FramesID, 0, 32767);
- repeat
- ModalDialog(nil, item);
- if item = FramesID then
- FramesToAverage := GetDNum(MyLog, FramesID);
- if item = SumID then begin
- SumFrames := not SumFrames;
- SetDialogItem(mylog, SumID, ord(SumFrames));
- end;
- if item = VideoRateID then begin
- VideoRateAveraging := not VideoRateAveraging;
- SetDialogItem(mylog, VideoRateID, ord(VideoRateAveraging));
- end;
- if item = ShowID then begin
- ShowIntegratedValues := not ShowIntegratedValues;
- SetDialogItem(mylog, ShowID, ord(ShowIntegratedValues));
- if ShowIntegratedValues then
- SumFrames := true;
- SetDialogItem(mylog, SumID, ord(SumFrames));
- end;
- if item = FixID then begin
- FixIntegrationScale := not FixIntegrationScale;
- SetDialogItem(mylog, FixID, ord(FixIntegrationScale));
- if FixIntegrationScale then
- SumFrames := true;
- SetDialogItem(mylog, SumID, ord(SumFrames));
- end;
- if (item = MinID) or (item = MaxID) then begin
- if item = MinID then
- IntegrationMin := GetDNum(MyLog, MinID)
- else
- IntegrationMax := GetDNum(MyLog, MaxID);
- SumFrames := true;
- SetDialogItem(mylog, SumID, ord(SumFrames));
- FixIntegrationScale := true;
- SetDialogItem(mylog, FixID, ord(FixIntegrationScale));
- end;
- until (item = ok) or (item = cancel);
- DisposDialog(mylog);
- if FramesToAverage < 2 then
- FramesToAverage := 2;
- if IntegrationMin < 0 then
- IntegrationMin := 0;
- if IntegrationMax > 32767 then
- IntegrationMax := 32767;
- if VideoRateAveraging and (item <> cancel) then begin
- if FrameGrabber <> ScionLG3 then begin
- VideoRateAveraging := false;
- PutMessage('Video rate capture requires a Scion LG-3.');
- DoAveragingOptions := false;
- exit(DoAveragingOptions);
- end;
- if FramesToAverage > MaxLG3Frames then begin
- FramesToAverage := MaxLG3Frames;
- DoAveragingOptions := false;
- PutMessage(concat('This ', long2str(MaxLG3Frames div 2), 'MB LG-3 can capture a maximum of ', long2str(MaxLG3Frames), ' frames at video rates.'));
- exit(DoAveragingOptions);
- end;
- end;
- DoAveragingOptions := item <> cancel;
- end;
-
-
- procedure AverageFrames;
- type
- IntPtr = ^integer;
- SumLineType = array[0..2047] of integer;
- sptr = ^SumLineType;
- var
- AutoSelectAll: boolean;
- SelectionSize, FrameBufferSize, offset, StartTicks: LongInt;
- SumBase, src, srcbase, dst, OffscreenBase: ptr;
- str1, str2: str255;
- xLines, xPixelsPerLine, BytesPerLine, frame, line, pixel: integer;
- aline, BlankLine: LineType;
- GrabRect: rect;
- DisplayPoint: point;
- hstart, vstart, wwidth, wheight: integer;
- j, FramesAveraged: integer;
- SrcRowBytes, DstRowBytes, i, value, MinV, MaxV, range, ActualMin, ActualMax: LongInt;
- iptr: IntPtr;
- FrameLine: LinePtr;
- SumLine: sptr;
- SaveBlankFieldInfo: InfoPtr;
- myMMUMode: signedbyte;
- begin
- with info^ do
- if (PictureType <> FrameGrabberType) and (PictureType <> ScionType) then begin
- PutMessage('You must have an active Camera window(created using Start Capturing) in order to average frames.');
- macro := false;
- exit(AverageFrames)
- end;
- if NotRectangular or NotinBounds then begin
- macro := false;
- exit(AverageFrames);
- end;
- if (not OptionKeyWasDown) and (not macro) then begin
- if not DoAveragingOptions then
- exit(AverageFrames);
- end;
- SaveBlankFieldInfo := BlankFieldInfo;
- BlankFieldInfo := nil; {We don't want to do shading correction now}
- StopDigitizing;
- BlankFieldInfo := SaveBlankFieldInfo;
- OptionKeyWasDown := false;
- DrawLabels('Frame:', 'Total:', '');
- ShowTriggerMessage;
- ShowWatch;
- AutoSelectAll := not Info^.RoiShowing;
- if AutoSelectAll then
- SelectAll(false);
- with info^.RoiRect do
- SelectionSize := (LongInt(right) - left) * (bottom - top);
- FrameBufferSize := SelectionSize * 2;
- if FrameBufferSize > BigBufSize then begin
- NumToString(FrameBufferSize div 1024, str1);
- NumToString(BigBufSize div 1024, str2);
- str2 := concat(str1, 'K bytes are required, but only ', str2, 'K bytes are available.');
- PutMessage(concat('There is not enough memory to do the requested frame averaging. ', str2));
- if AutoSelectAll or (BlankFieldInfo <> nil) then
- KillRoi
- else
- ShowRoi;
- exit(AverageFrames)
- end;
- WhatToUndo := NothingToUndo;
- WhatsOnClip := NothingOnClip;
- SumBase := BigBuf;
- case FrameGrabber of
- QuickCapture: begin
- ContinuousHistogram := false;
- ResetQuickCapture
- end;
- ScionLG3: begin
- ContinuousHistogram := false;
- ResetScionLG3
- end;
- Scion: begin
- with info^.wrect do begin
- wwidth := right;
- wheight := bottom;
- end;
- hstart := (640 - wwidth) div 2;
- vstart := (480 - wheight) div 2;
- SetRect(GrabRect, hstart, vstart, hstart + wwidth, vstart + wheight);
- with DisplayPoint do begin
- h := PicLeftBase;
- v := PicTopBase;
- end;
- ResetScion(GrabRect, DisplayPoint);
- HideCursor;
- end;
- end; {case}
- with info^, info^.RoiRect do begin
- offset := left + LongInt(top) * BytesPerRow;
- OffscreenBase := ptr(ord4(PicBaseAddr) + offset);
- if FrameGrabber = Scion then
- with DisplayPoint do begin
- BringToFront(wptr);
- offset := left + h + (v + top) * ScreenRowBytes;
- srcbase := ptr(ord4(ScreenBase) + offset);
- SrcRowBytes := ScreenRowBytes;
- end
- else begin
- offset := left + LongInt(top) * fgRowBytes;
- srcbase := ptr(ord4(ptr(fgSlotBase)) + offset);
- SrcRowBytes := fgRowBytes;
- end;
- xLines := bottom - top;
- xPixelsPerLine := right - left;
- BytesPerLine := xPixelsPerLine * 2;
- end; {with}
- for i := 0 to BytesPerLine - 1 do
- BlankLine[i] := WhiteIndex;
- dst := SumBase;
- for line := 1 to xLines do begin {zero buffer}
- BlockMove(@BlankLine, dst, BytesPerLine);
- dst := ptr(ord4(dst) + BytesPerLine);
- end;
- info^.title := 'Camera';
- UpdateTitleBar;
- StartTicks := TickCount;
- if FrameGrabber <> ScionLG3 then
- VideoRateAveraging := false;
- if VideoRateAveraging then begin
- if FramesToAverage > MaxLG3Frames then
- FramesToAverage := MaxLG3Frames;
- ExternalTrigger := false;
- BufferReg^ := 0;
- GetFrame;
- StartTicks := TickCount - 2;
- for frame := 1 to FramesToAverage - 1 do begin
- BufferReg^ := Frame;
- GetFrame;
- end;
- BufferReg^ := 0;
- RealToString((TickCount - StartTicks) / 60.0, 1, 2, str1);
- ShowFrameRate(concat(Long2str(FramesToAverage), ' frames', cr, str1, ' seconds', cr), StartTicks, FramesToAverage);
- end;
- for frame := 0 to FramesToAverage - 1 do begin
- Show2Values(frame + 1, FramesToAverage);
- if VideoRateAveraging then
- BufferReg^ := Frame
- else begin
- if FrameGrabber = Scion then
- GetScionFrame(DisplayPoint)
- else
- GetFrame;
- end;
- src := srcbase;
- dst := SumBase;
- myMMUMode := 1;
- SwapMMUMode(myMMUMode);
- for line := 1 to xLines do begin
- AddLineToSum(src, dst, xPixelsPerLine);
- src := ptr(ord4(src) + SrcRowBytes);
- dst := ptr(ord4(dst) + BytesPerLine);
- end;
- SwapMMUMode(myMMUMode);
- if FrameGrabber <> Scion then
- UpdateScreen(info^.RoiRect);
- if CommandPeriod then begin
- beep;
- if AutoSelectAll then
- KillRoi
- else
- ShowRoi;
- exit(AverageFrames);
- end;
- end; {for}
- src := SumBase;
- dst := OffscreenBase;
- DstRowBytes := info^.BytesPerRow;
- if SumFrames then begin
- MinV := 2000000000;
- MaxV := 0;
- iptr := IntPtr(src);
- for i := 1 to SelectionSize do begin
- value := iptr^;
- if value > MaxV then
- MaxV := value;
- if value < MinV then
- MinV := value;
- iptr := IntPtr(ord4(iptr) + 2);
- end;
- ActualMin := MinV;
- ActualMax := MaxV;
- if FixIntegrationScale then begin
- MinV := IntegrationMin;
- MaxV := IntegrationMax;
- end;
- range := MaxV - MinV;
- if range <> 0 then
- for line := 1 to xLines do begin
- SumLine := sptr(src);
- FrameLine := LinePtr(dst);
- for j := 0 to xPixelsPerLine - 1 do begin
- value := LongInt(SumLine^[j] - MinV) * 253 div range + 1;
- if value < 0 then
- value := 0;
- if value > 255 then
- value := 255;
- FrameLine^[j] := value;
- end;
- src := ptr(ord4(src) + BytesPerLine);
- dst := ptr(ord4(dst) + DstRowBytes);
- end
- else
- beep;
- end
- else
- for line := 1 to xLines do begin
- SumLine := sptr(src);
- FrameLine := LinePtr(dst);
- for j := 0 to xPixelsPerLine - 1 do
- FrameLine^[j] := SumLine^[j] div FramesToAverage;
- src := ptr(ord4(src) + BytesPerLine);
- dst := ptr(ord4(dst) + DstRowBytes);
- end;
- if not VideoRateAveraging then begin
- if SumFrames then begin
- if FixIntegrationScale then
- str1 := concat('min=', long2str(MinV), ' (', long2str(ActualMin), ')', cr, 'max=', long2str(MaxV), ' (', long2str(ActualMax), ')', cr)
- else
- str1 := concat('min=', long2str(MinV), cr, 'max=', long2str(MaxV), cr)
- end
- else
- str1 := '';
- RealToString((TickCount - StartTicks) / 60.0, 1, 2, str2);
- ShowFrameRate(concat(Long2str(FramesToAverage), ' frames', cr, str1, str2, ' seconds', cr), StartTicks, FramesToAverage);
- end;
- UpdatePicWindow;
- if AutoSelectAll then
- KillRoi
- else
- ShowRoi;
- if BlankFieldInfo <> nil then
- CorrectShading;
- if ShowIntegratedValues then
- with info^ do begin
- DensityCalibrated := true;
- fit := StraightLine;
- nCoefficients := 2;
- coefficient[2] := (MaxV - MinV) / 253.0;
- coefficient[1] := MinV - coefficient[2];
- ZeroClip := false;
- UpdateTitleBar;
- if macro then
- GenerateValues;
- end
- end;
-
-
- function GetFGPixel (h, v: integer): integer;
- var
- offset: LongInt;
- p: ptr;
- begin
- with Info^ do begin
- if (h < 0) or (v < 0) or (h >= fgWidth) or (v >= fgHeight) then begin
- GetFGPixel := WhiteIndex;
- exit(GetFGPixel);
- end;
- offset := LongInt(v) * fgRowBytes + h;
- if offset >= LongInt(fgHeight) * fgRowBytes then begin
- GetFGPixel := WhiteIndex;
- exit(GetFGPixel);
- end;
- p := ptr(ord4(ptr(fgSlotBase)) + offset);
- GetFGPixel := BAND(p^, 255);
- end;
- end;
-
-
- procedure WaitForTrigger;
- begin
- StopDigitizing;
- ShowWatch;
- case FrameGrabber of
- QuickCapture: begin
- ControlReg^ := BitAnd($82, 255); {Wait for external trigger and capture one frame}
- repeat
- until (ControlReg^ >= 0) or Button; {Wait for it to complete}
- end;
- ScionLG3: begin
- ControlReg^ := $90; {Wait for external trigger and capture one frame}
- repeat
- until (BitAnd(ControlReg^, $80) = $80) or Button; {Wait for it to complete}
- end;
- otherwise
- repeat
- until Button;
- end;
- end;
-
-
- procedure SetOffset (var offset, gain: integer);
- begin
- if offset < 0 then
- offset := 0;
- if offset > 255 then
- offset := 255;
- if offset > gain then
- offset := gain;
- LG3DacLow := offset;
- LG3DacHigh := LG3DacLow + (255 - gain);
- end;
-
-
- procedure SetGain (var offset, gain: integer);
- begin
- if gain < 0 then
- gain := 0;
- if gain > 255 then
- gain := 255;
- if gain < LG3DacLow then
- gain := LG3DacLow;
- LG3DacHigh := LG3DacLow + (255 - gain);
- end;
-
-
- procedure ShowChannel;
- begin
- SetDialogItem(VideoControl, FirstChannelID, ord(VideoChannel = 0));
- SetDialogItem(VideoControl, FirstChannelID + 1, ord(VideoChannel = 1));
- SetDialogItem(VideoControl, FirstChannelID + 2, ord(VideoChannel = 2));
- SetDialogItem(VideoControl, FirstChannelID + 3, ord(VideoChannel = 3));
- end;
-
-
- procedure UpdateVideoControl;
- begin
- if VideoControl <> nil then
- SetDialogItem(VideoControl, TriggerID, ord(ExternalTrigger));
- end;
-
-
- procedure ShowOffsetAndGain (offset, gain: integer);
- var
- str: str255;
- begin
- RealToString(offset, 3, 0, str);
- if str[1] = ' ' then
- str[1] := '0';
- if str[2] = ' ' then
- str[2] := '0';
- SetDString(VideoControl, OffsetID, str);
- RealToString(gain, 3, 0, str);
- if str[1] = ' ' then
- str[1] := '0';
- if str[2] = ' ' then
- str[2] := '0';
- SetDString(VideoControl, GainID, str);
- end;
-
-
- procedure ShowVideoControl;
- var
- gain: integer;
- begin
- InitCursor;
- VideoControl := GetNewDialog(130, nil, pointer(-1));
- ShowChannel;
- SetDialogItem(VideoControl, InvertID, ord(InvertVideo));
- SetDialogItem(VideoControl, HighlightID, ord(HighlightSaturatedPixels));
- SetDialogItem(VideoControl, OscillatingID, ord(OscillatingMovies));
- SetDialogItem(VideoControl, TriggerID, ord(ExternalTrigger));
- SetDialogItem(VideoControl, BlindID, ord(BlindMovieCapture));
- SetDialogItem(VideoControl, SyncID, ord(SyncMode = SeparateSync));
- gain := 255 - (LG3DacHigh - LG3DacLow);
- ShowOffsetAndGain(LG3DacLow, gain);
- end;
-
-
- procedure DoVideoControl (item: integer);
- var
- i: integer;
- OutOfRange, WasDigitizing: boolean;
- offset, gain, inc, count: integer;
-
- procedure CheckFrameGrabber;
- begin
- if FrameGrabber <> ScionLG3 then begin
- PutMessage('Programmable offset and gain are only supported on the Scion LG-3.');
- exit(DoVideoControl);
- end;
- end;
-
- procedure SetVideoItem (item, value: integer);
- begin
- if VideoControl <> nil then
- SetDialogItem(VideoControl, item, value);
- end;
-
- begin
- InitCursor;
- gain := 255 - (LG3DacHigh - LG3DacLow);
- if (item >= FirstChannelID) and (item <= (FirstChannelID + 3)) then begin
- VideoChannel := item - FirstChannelID;
- if VideoControl <> nil then
- ShowChannel;
- if digitizing then
- ResetFrameGrabber;
- end;
- if item = InvertID then begin
- InvertVideo := not InvertVideo;
- SetVideoItem(InvertID, ord(InvertVideo));
- if digitizing then
- ResetFrameGrabber;
- end;
- if item = HighlightID then begin
- HighlightSaturatedPixels := not HighlightSaturatedPixels;
- SetVideoItem(HighlightID, ord(HighlightSaturatedPixels));
- if digitizing then begin
- if HighlightSaturatedPixels then
- HighlightPixels
- else
- LoadLUT(info^.ctable);
- end;
- end;
- if item = OscillatingID then begin
- OscillatingMovies := not OscillatingMovies;
- SetVideoItem(OscillatingID, ord(OscillatingMovies));
- end;
- if item = TriggerID then begin
- ExternalTrigger := not ExternalTrigger;
- case FrameGrabber of
- QuickCapture, ScionLG3: begin
- WasDigitizing := digitizing;
- StopDigitizing;
- if ExternalTrigger and WasDigitizing then
- StartDigitizing;
- end;
- otherwise
- ExternalTrigger := false;
- end;
- SetVideoItem(TriggerID, ord(ExternalTrigger));
- end;
- if item = BlindID then begin
- BlindMovieCapture := not BlindMovieCapture;
- SetVideoItem(BlindID, ord(BlindMovieCapture));
- end;
- if item = SyncID then begin
- if SyncMode <> SeparateSync then
- SyncMode := SeparateSync
- else
- SyncMode := NormalSync;
- case FrameGrabber of
- ScionLG3:
- if digitizing then
- ResetFrameGrabber;
- QuickCapture: begin
- PutMessage('Sync is not under program control on the QuickCapure card.');
- SyncMode := NormalSync;
- macro := false;
- end;
- otherwise
- ;
- end;
- SetVideoItem(SyncID, ord(SyncMode = SeparateSync));
- end;
- if (item >= OffsetUpID) and (item <= GainDownID) then begin
- CheckFrameGrabber;
- offset := LG3DacLow;
- inc := 1;
- count := 0;
- repeat
- count := count + 1;
- if count > 2 then
- inc := 2;
- if count > 4 then
- inc := 5;
- if count > 8 then
- inc := 10;
- case item of
- OffsetUpID: begin
- offset := offset + inc;
- SetOffset(offset, gain);
- end;
- OffsetDownID: begin
- offset := offset - inc;
- SetOffset(offset, gain);
- end;
- GainUpID: begin
- gain := gain + inc;
- SetGain(offset, gain);
- end;
- GainDownID: begin
- gain := gain - inc;
- SetGain(offset, gain);
- end;
- end; {case}
- ShowOffsetAndGain(LG3DacLow, gain);
- if Digitizing and (count > 1) then begin
- DacLowReg^ := LG3DacLow;
- DacHighReg^ := LG3DacHigh;
- CaptureAndDisplayFrame;
- if ContinuousHistogram then begin
- ShowContinuousHistogram;
- DrawHistogram
- end
- end
- else
- wait(5);
- until not button;
- end;
- if item = ResetID then begin
- CheckFrameGrabber;
- LG3DacLow := DefaultLG3DacLow;
- LG3DacHigh := DefaultLG3DacHigh;
- gain := 255 - (LG3DacHigh - LG3DacLow);
- ParamText(long2str(LG3DacLow), long2str(gain), '', '');
- ShowOffsetAndGain(LG3DacLow, gain);
- end;
- if FramesToAverage < 2 then
- FramesToAverage := 2;
- if (FrameGrabber = Scion) and (ExternalTrigger or BlindMovieCapture) then begin
- PutMessage('External triggering and blind movie capture are not supported with the SCION frame grabber card.');
- ExternalTrigger := false;
- BlindMovieCapture := false;
- end;
- if FrameGrabber = ScionLG3 then begin
- DacLowReg^ := LG3DacLow;
- DacHighReg^ := LG3DacHigh;
- end;
- end;
-
-
- end.